#coding=utf-8
#LightCam 熔断脚本
#init by hfh 20151113

import multiprocessing,subprocess,sys
import socket,os,time,re,traceback,json,binascii
import lc_libs,pymongo

def breaker_init(filename,flagfile):

	#排队机时间
	Breaker['CurrentTime']=""
	#现货行情
	Breaker['ProductName']=""
	Breaker['PreClosePx']=0.0
	Breaker['OpenPrice']=0.0
	Breaker['HighPrice']=0.0
	Breaker['LowPrice']=0.0
	Breaker['TradePrice']=0.0
	Breaker['ClosePx']=0.0
	Breaker['SpotMarketDataTime']=""
	#交易日
	Breaker['TradingDay']=""
	#熔断状态
	Breaker['FuseStatus']=""
	#交割日合约信息
	#前置连接状态
	Breaker['FrontConStatus']=""
	#前置登录状态
	Breaker['FrontLogStatus']=""
	#MdScan连接状态
	Breaker['MdScanConStatus']=""
	#fuse进程状态
	Breaker['fuseprocess']=""
	Breaker['plan_to_dbprocess']=""
	#CmdSender线程状态
	Breaker['CmdSenderStatuss']=""
	#MdReceiver线程状态
	Breaker['MdReceiverStatus']=""
	#基准昨收盘价
	Breaker['CLOSE_PRICE']=0.0
	#涨跌幅初始化
	Breaker['HighPercent']=0.0
	Breaker['LowPercent']=0.0
	Breaker['TradePercent']=0.0

	#日志列表
	del events[0:]
	#执行进度表
	del crond[0:]
	#行情
	del quote[0:]
	#进程
	del process[0:]
	#应用状态
	del appstatus[0:]

	#重置标志文件
	fc=open(flagfile,'w')
	fc.write(str(0))
	fc.close()
	
def gen_jsonfile(filename,flagfile):
	
	#生成事件列表JSON文件
	file=open("/monitor/LightCam/temp/events.json",'w')
	file.write(json.dumps(events))
	file.close()
	
	#生成熔断进度JSON文件
	file=open("/monitor/LightCam/temp/crond.json",'w')
	file.write(json.dumps(crond))
	file.close()
	
	#状态信息
	appstatus=[
		{'hostname':agent_hostname,"name":"排队机时间","value":Breaker['CurrentTime']},
		{'hostname':agent_hostname,"name":"现货行情时间","value":Breaker['SpotMarketDataTime']},
		{'hostname':agent_hostname,"name":"交易日","value":Breaker['TradingDay']},
		{'hostname':agent_hostname,"name":"熔断状态","value":Breaker['FuseStatus']},
		{'hostname':agent_hostname,"name":"前置连接状态","value":Breaker['FrontConStatus']},
		{'hostname':agent_hostname,"name":"前置登录状态","value":Breaker['FrontLogStatus']},
		{'hostname':agent_hostname,"name":"MdScan连接状态","value":Breaker['MdScanConStatus']},
		{'hostname':agent_hostname,'name':"基准昨收盘价",'value':Breaker['CLOSE_PRICE']},
		{'hostname':agent_hostname,'name':"熔断触发点数+5%",'value':round(Breaker['CLOSE_PRICE']*1.05,4)},
		{'hostname':agent_hostname,'name':"熔断触发点数+7%",'value':round(Breaker['CLOSE_PRICE']*1.07,4)},
		{'hostname':agent_hostname,'name':"熔断触发点数-5%",'value':round(Breaker['CLOSE_PRICE']*0.95,4)},
		{'hostname':agent_hostname,'name':"熔断触发点数-7%",'value':round(Breaker['CLOSE_PRICE']*0.93,4)},
	]
	#生成状态信息JSON文件
	file=open("/monitor/LightCam/temp/appstatus.json",'w')
	file.write(json.dumps(appstatus))
	file.close()
	
	#行情信息
	quote=[
		{'hostname':agent_hostname,"name":"现货行情时间","value":Breaker['SpotMarketDataTime']},
		{'hostname':agent_hostname,'name':"基准昨收盘价",'value':Breaker['CLOSE_PRICE']},
		{'hostname':agent_hostname,'name':"昨收盘价",'value':Breaker['PreClosePx']},
		{'hostname':agent_hostname,'name':"开盘价",'value':Breaker['OpenPrice']},
		{'hostname':agent_hostname,'name':"最高价",'value':Breaker['HighPrice']},
		{'hostname':agent_hostname,'name':"最低价",'value':Breaker['LowPrice']},
		{'hostname':agent_hostname,'name':"最新价",'value':Breaker['TradePrice']},
		{'hostname':agent_hostname,'name':"收盘价",'value':Breaker['ClosePx']},
		{'hostname':agent_hostname,'name':"最高涨幅",'value':str(Breaker['HighPercent'])+"%"},
		{'hostname':agent_hostname,'name':"最低跌幅",'value':str(Breaker['LowPercent'])+"%"},
		{'hostname':agent_hostname,'name':"当前涨幅",'value':str(Breaker['TradePercent'])+"%"},
	]
	#生成行情JSON文件
	file=open("/monitor/LightCam/temp/quote.json",'w')
	file.write(json.dumps(quote))
	file.close()
	
	#进程状态
	comd="ps -ef|grep -v grep|grep -c -w fuse"
	popen=subprocess.Popen(comd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
	res=popen.stdout.read().strip('\n\r\t ')
	try:
		res=int(res)
	except:
		res=0
	if res>0:
		Breaker['fuseprocess']="正常"
	else:
		Breaker['fuseprocess']="异常"

	#进程状态
	comd="ps -ef|grep -v grep|grep -c -w plan_to_db"
	popen=subprocess.Popen(comd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
	res=popen.stdout.read().strip('\n\r\t ')
	try:
		res=int(res)
	except:
		res=0
	if res>0:
		Breaker['plan_to_dbprocess']="正常"
	else:
		Breaker['plan_to_dbprocess']="异常"

	process=[
		{'hostname':agent_hostname,'process':"fuse",'status':Breaker['fuseprocess']},
		{'hostname':agent_hostname,'process':"plan_to_db",'status':Breaker['plan_to_dbprocess']},
		{'hostname':agent_hostname,'process':"CmdSender",'status':Breaker['CmdSenderStatuss']},
		{'hostname':agent_hostname,'process':"MdReceiver",'status':Breaker['MdReceiverStatus']},
		]

	#生成进程状态JSON文件
	file=open("/monitor/LightCam/temp/process.json",'w')
	file.write(json.dumps(process))
	file.close()


def gen_logfile(filename,flagfile):
	
	try:
		Node=agent_hostname
		AlertGroup="TradeBreaker"
		
		today=time.strftime('%Y%m%d',time.localtime())
		
		if os.path.exists(filename)==False:
			print "File not exist"
			breaker_init(filename,flagfile)
			time.sleep(10)
			return 0
		
		nsize=os.path.getsize(filename)
		fr=open(filename,'rb')
		try:
			fc=open(flagfile,'r+')
		except IOError:
			pointer=nsize
			fc=open(flagfile,'w')
			fc.write(str(pointer))
			fc.close()
			fc=open(flagfile,'r+')
		
		pointer=int(fc.read())
		if nsize < pointer:
			print "file rebuild"
			pointer=0
			breaker_init(filename,flagfile)
		
		fr.seek(pointer,0)
		buf=fr.read()
		if len(buf)==0:
			fc.close()
			fr.close()
			return 0
		pointer=fr.tell()
		fc.seek(0,0)
		fc.truncate()
		fc.write(str(pointer))
		fc.close()
		fr.close()
		
		for filecontent in buf.split('\n'):
			if str(filecontent) == "":
				continue
			try:
				filecontent=filecontent.decode('gbk').encode('utf8')
			except:
				pass
			lines=filecontent.split()
			if len(lines)<5:
				continue
			
			#事件列表
			if len(lines)>9:
				EventsSeverity=lines[8]
				if EventsSeverity in ['1','2','3']:
					info={
						'time':lines[0]+" "+lines[1]+" "+lines[2],
						'hostname':agent_hostname,
						'datastr':lines[6:]
					}
					events.append(info)
					if len(events)>100:
						del events[0]
					
			#熔断执行进度
			if "DoExecute" in filecontent:
				res=re.findall(r"Field\[(.*)\]",filecontent,re.S)
				if len(res) <> 0:
					datastr=res[0]
				if len(lines)>10:
					info={
						'hostname':agent_hostname,
						'time':lines[0]+" "+lines[1]+" "+lines[2],
						'command':lines[10].strip(', '),
						'datastr':datastr
					}
					crond.append(info)
				if len(crond)>100:
					del crond[0]
					
			#排队机时间
			if ' CurrentTime ' in filecontent:
				res=re.findall(r"([0-9]{2}:[0-9]{2}:[0-9]{2})",filecontent,re.S)
				if len(res) <> 0:
					Breaker['CurrentTime']=res[0]
			elif 'CompositorTime[' in filecontent:
				res=re.findall(r"CompositorTime\[([0-9]{2}:[0-9]{2}:[0-9]{2})",filecontent,re.S)
				if len(res) <> 0:
					Breaker['CurrentTime']=res[0]
			elif 'CurrentTime[' in filecontent:
				res=re.findall(r"CurrentTime\[([0-9]{2}:[0-9]{2}:[0-9]{2})",filecontent,re.S)
				if len(res) <> 0:
					Breaker['CurrentTime']=res[0]

			#现货行情
			if "SpotMarketDataTime" in filecontent:
				res=re.findall(r"ProductName\[(.*)\], PreClosePx",filecontent,re.S)
				if len(res) <> 0:
					Breaker['ProductName']=res[0]
				res=re.findall(r"PreClosePx\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['PreClosePx']=float(res[0])
				res=re.findall(r"OpenPrice\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['OpenPrice']=float(res[0])
				res=re.findall(r"HighPrice\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['HighPrice']=float(res[0])
				res=re.findall(r"LowPrice\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['LowPrice']=float(res[0])
				res=re.findall(r"TradePrice\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['TradePrice']=float(res[0])
				res=re.findall(r" ClosePx\[([0-9]+\.[0-9]+)\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['ClosePx']=float(res[0])
				res=re.findall(r"SpotMarketDataTime\[([0-9]{2}:[0-9]{2}:[0-9]{2})\]",filecontent,re.S)
				if len(res) <> 0:
					Breaker['SpotMarketDataTime']=res[0]
				if Breaker['CLOSE_PRICE'] != '':
					Breaker['HighPercent']="%.2f" % ((Breaker['HighPrice']/Breaker['CLOSE_PRICE']-1)*100)
					Breaker['LowPercent']="%.2f" % ((Breaker['LowPrice']/Breaker['CLOSE_PRICE']-1)*100)
					Breaker['TradePercent']="%.2f" % ((Breaker['TradePrice']/Breaker['CLOSE_PRICE']-1)*100)
				#发送告警事件
				if Breaker['TradePercent']<-4:
					TimeStr="%s %s %s" % (lines[0],lines[1],lines[2])
					Severity="5"
					Type="1"
					AlertKey="SpotMarketData -4% " + Breaker['TradingDay']
					Summary="%s,当前现货行情涨跌幅为%s,请关注!最新价:%s,昨收盘:%s,最高价:%s,最高涨幅:%s,最低价:%s,最低涨幅:%s" % (TimeStr,Breaker['TradePercent'],Breaker['TradePrice'],Breaker['CLOSE_PRICE'],Breaker['HighPrice'],Breaker['HighPercent'],Breaker['LowPrice'],Breaker['LowPercent'])
					strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
					print strs
					db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				elif Breaker['TradePercent']>-4 and Breaker['TradePercent']<0:
					TimeStr="%s %s %s" % (lines[0],lines[1],lines[2])
					Severity="2"
					Type="2"
					AlertKey="SpotMarketData -4% " + Breaker['TradingDay']
					Summary="%s,当前现货行情涨跌幅为%s,请关注!最新价:%s,昨收盘:%s,最高价:%s,最高涨幅:%s,最低价:%s,最低涨幅:%s" % (TimeStr,Breaker['TradePercent'],Breaker['TradePrice'],Breaker['CLOSE_PRICE'],Breaker['HighPrice'],Breaker['HighPercent'],Breaker['LowPrice'],Breaker['LowPercent'])
					strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
					print strs
					db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				elif Breaker['TradePercent']>0 and Breaker['TradePercent']<4:
					TimeStr="%s %s %s" % (lines[0],lines[1],lines[2])
					Severity="2"
					Type="2"
					AlertKey="SpotMarketData 4% " + Breaker['TradingDay']
					Summary="%s,当前现货行情涨跌幅为%s,请关注!最新价:%s,昨收盘:%s,最高价:%s,最高涨幅:%s,最低价:%s,最低涨幅:%s" % (TimeStr,Breaker['TradePercent'],Breaker['TradePrice'],Breaker['CLOSE_PRICE'],Breaker['HighPrice'],Breaker['HighPercent'],Breaker['LowPrice'],Breaker['LowPercent'])
					strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
					print strs
					db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				elif Breaker['TradePercent']>4 :
					TimeStr="%s %s %s" % (lines[0],lines[1],lines[2])
					Severity="5"
					Type="1"
					AlertKey="SpotMarketData 4% " + Breaker['TradingDay']
					Summary="%s,当前现货行情涨跌幅为%s,请关注!最新价:%s,昨收盘:%s,最高价:%s,最高涨幅:%s,最低价:%s,最低涨幅:%s" % (TimeStr,Breaker['TradePercent'],Breaker['TradePrice'],Breaker['CLOSE_PRICE'],Breaker['HighPrice'],Breaker['HighPercent'],Breaker['LowPrice'],Breaker['LowPercent'])
					strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
					print strs
					db.update_eventsdb(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)

			#交易日
			if "OnNtfCommPhaseChange" in filecontent:
				res=re.findall(r"([0-9]{8})",filecontent,re.S)
				if len(res) <> 0:
					Breaker['TradingDay']=res[0]
			#熔断状态
			if "ReportFuseEvent" in filecontent:
				Breaker['FuseStatus']="触发"
				#发送告警事件
				TimeStr="%s %s %s" % (lines[0],lines[1],lines[2])
				Severity="5"
				Type="1"
				AlertKey="ReportFuseEvent %s %s" % (Breaker['TradePercent'],Breaker['TradingDay'])
				Summary="%s,触发熔断!当前现货行情涨跌幅为%s,最新价:%s,昨收盘:%s,最高价:%s,最高涨幅:%s,最低价:%s,最低涨幅:%s" % (TimeStr,Breaker['TradePercent'],Breaker['TradePrice'],Breaker['CLOSE_PRICE'],Breaker['HighPrice'],Breaker['HighPercent'],Breaker['LowPrice'],Breaker['LowPercent'])
				strs=lc_libs.lc_gen_alert(agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
				print strs
				db.update_eventsdb_rt(events_table,agent_hostname,Node,AlertGroup,AlertKey,Severity,Type,Summary)
			#前置连接状态
			if "OnFrontConnected" in filecontent:
				Breaker['FrontConStatus']="已连接"
			if "OnFrontDisConnected" in filecontent:
				Breaker['FrontConStatus']="未连接"
			#前置登录状态
			if "OnRspUserLogin" in filecontent:
				Breaker['FrontLogStatus']="已登录"
			if "OnRspUserLogout" in filecontent:
				Breaker['FrontLogStatus']="未登录"
			#MdScan连接状态
			if "OnSessionConnected" in filecontent:
				Breaker['MdScanConStatus']="已连接"
			if "OnSessionDisconnected" in filecontent:
				Breaker['MdScanConStatus']="未连接"
			if "CmdSender:::DoSelfCheck" in filecontent:
				Breaker['CmdSenderStatuss']=lines[2]
			if "CMdReceiver:::DoSelfCheck" in filecontent:
				Breaker['MdReceiverStatus']=lines[2]
			#基准昨收盘价
			if "CLOSE_PRICE" in filecontent:
				res=re.findall(r"CLOSE_PRICE=([0-9]+\.[0-9]+)",filecontent,re.S)
				if len(res) <> 0:
					Breaker['CLOSE_PRICE']=float(res[0])
	
		
	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" :\n"+excinfo+"\n")
		logfile.flush()
		time.sleep(10)

def gen_processstatus():
	processstatus=[]
	try:
		comd=r'''
			ps -fu trade|awk 'NR>1{for(i=8;i<=NF;++i) printf $i " ";printf "\n"}'
		'''

		popen=subprocess.Popen(comd,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
		for line in popen.stdout.read().split('\n'):
			if len(line)<3:
				continue
			info={
				'hostname':agent_hostname,
				'process':line.strip('\r\n ')
			}
			processstatus.append(info)
		#print processstatus
		file=open("/monitor/LightCam/temp/process.json",'w')
		file.write(json.dumps(processstatus))
		file.close()
	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" :\n"+excinfo+"\n")
		logfile.flush()

if __name__ == "__main__":
	
	lchome=lc_libs.lc_getlchome()
	scname=sys.argv[0].split('.')[0]
	logfilename=lchome+'/log/'+scname+'.log'
	confname=lchome+'/conf/'+scname+'.conf'
	
	today=time.strftime('%Y%m%d',time.localtime())
	os.system("mv %s %s.%s" % (logfilename,logfilename,today))
	
	logfile=file(logfilename,'a')
	logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
	logfile.write(logdate+" Started.\n")
	logfile.flush()

	agent_hostname=lc_libs.lc_gethostname()
	
	#初始化数据库
	try:
		
		db=lc_libs.lc_mongodb_operater('127.0.0.1',27017)

		db.connect()
		Conn=db.getConn()
		if Conn==None:
			print "Can not Connect to the MondbDB"
			exit(0)
		
		events_dbname='lc_events'
		events_tablename='lc_events'
		
		events_db=db.useDatabase(events_dbname)
		events_table=db.UseCollection(events_db,events_tablename)

	except Exception:
		excinfo=traceback.format_exc()
		logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
		logfile.write(logdate+" 初始化数据库失败:\n"+excinfo+"\n")
		logfile.flush()
		exit(0)

	#主程序

	#日志列表
	events=[]
	
	#执行进度表
	crond=[]

	#行情
	quote=[]
	
	#进程
	process=[]
	
	#应用状态
	appstatus=[]

	#日志文件定义
	filename="/cffex/trade/%s/bin/Syslog.log" % agent_hostname
	#filename="/monitor/LightCam/temp/Syslog.log"
	
	#标志文件定义
	flagfile=lchome+'/flag/breakerfile__'+filename.replace('/','_')
	
	#标志文件清理
	os.system("rm -rf %s " % flagfile)

	#数据初始化
	Breaker={}
	breaker_init(filename,flagfile)
	

	while True:
		time.sleep(0.1)
		try:
			gen_logfile(filename,flagfile)
			gen_jsonfile(filename,flagfile)
			time.sleep(1)
		except Exception:
			excinfo=traceback.format_exc()
			logdate=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())
			logfile.write(logdate+" \n"+excinfo+"\n")
			logfile.flush()
			time.sleep(10)
